package com.rt.gptnext.config;

import cn.hutool.core.util.StrUtil;
import com.rt.gptnext.common.bean.HttpResult;
import com.rt.gptnext.common.exception.BusinessException;
import com.rt.gptnext.common.exception.IResultCode;
import com.rt.gptnext.common.exception.ResultCode;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
import org.springframework.web.servlet.NoHandlerFoundException;

/**
 * @author gaoyiyang
 **/
@Slf4j
@ControllerAdvice
public class GlobalErrorAdvice {

    @ExceptionHandler(BusinessException.class)
    @ResponseBody
    public HttpResult<Void> handleBusinessException(BusinessException e, HttpServletResponse response) {
        log.error("捕获到业务异常", e);
        IResultCode code = e.getCode();
        if (code == ResultCode.NOT_HAS_AUTHORITY || code == ResultCode.REQUIRED_LOGIN) {
            response.setStatus(HttpStatus.UNAUTHORIZED.value());
        }
        return HttpResult.failure(e.getCode(), e.getMessage());
    }


    @ExceptionHandler(BindException.class)
    @ResponseBody
    public HttpResult<Void> handleBindException(BindException e) {
        log.error("捕获到参数绑定异常", e);
//        saveErrorLog(e);
        BindingResult result = e.getBindingResult();
        FieldError fieldError = result.getFieldError();
        return HttpResult.failure(ResultCode.VALIDATE_FIELD_ERROR, StrUtil.format("{}:{}", fieldError.getField(), fieldError.getDefaultMessage()));
    }

    @ExceptionHandler(MissingServletRequestParameterException.class)
    @ResponseBody
    public HttpResult<Void> handleMissingServletRequestParameterException(MissingServletRequestParameterException e) {
        log.error("获取到参数缺失异常", e);
//        saveErrorLog(e);
        return HttpResult.failure(ResultCode.VALIDATE_FIELD_ERROR, StrUtil.format("{}:query参数不能为空", e.getParameterName()));
    }

    @ExceptionHandler(MethodArgumentTypeMismatchException.class)
    @ResponseBody
    public HttpResult<Void> handleMethodArgumentTypeMismatchException(MethodArgumentTypeMismatchException e) {
        log.error("获取到参数类型异常", e);
//        saveErrorLog(e);
        return HttpResult.failure(ResultCode.VALIDATE_FIELD_ERROR, StrUtil.format("{}:参数类型错误", e.getValue()));
    }

    @ExceptionHandler(NoHandlerFoundException.class)
    @ResponseBody
    @ResponseStatus(HttpStatus.NOT_FOUND)
    public HttpResult<Void> handleNoHandlerFoundException(NoHandlerFoundException e) {
        log.error("捕获到NoHandlerFoundException", e);
        return HttpResult.failure(ResultCode.NOT_FOUND_API);
    }

    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    @ResponseBody
    @ResponseStatus(HttpStatus.NOT_FOUND)
    public HttpResult<Void> handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e) {
        log.error("捕获到HttpRequestMethodNotSupportedException", e);
        return HttpResult.failure(ResultCode.NOT_SUPPORT_REQUEST_METHOD, "该接口不支持请求方法:" + e.getMethod());
    }

    @ExceptionHandler(Exception.class)
    @ResponseBody
    public HttpResult<Void> handleException(Exception e) {
        log.error("捕获到全局异常", e);
        return HttpResult.failure(ResultCode.SYSTEM_ERROR);
    }


}
